﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Fast.RemoteRequest
{
    [SkipScan]
    public static class HttpRemoteRequestStringExtensions
    {
        /// <summary>
        /// 设置客户端分类名
        /// </summary>
        /// <param name="url"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetClientName(this string url, string name)
            => RemoteRequest.SetRequestUrl(url).SetClientName(name);

        /// <summary>
        /// 设置超时时间
        /// </summary>
        /// <param name="url"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetClientTimeout(this string url, TimeSpan timeout)
            => RemoteRequest.SetRequestUrl(url).SetClientTimeout(timeout);

        /// <summary>
        /// 设置超时时间（秒）
        /// </summary>
        /// <param name="url"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetClientTimeout(this string url, long timeout)
            => RemoteRequest.SetRequestUrl(url).SetClientTimeout(timeout);

        /// <summary>
        /// 设置 URL 参数
        /// </summary>
        /// <param name="url"></param>
        /// <param name="queryParams"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetQueryParams(this string url, IDictionary<string, object> queryParams)
            => RemoteRequest.SetRequestUrl(url).SetQueryParams(queryParams);

        /// <summary>
        /// 设置 URL 参数
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetQueryParams(this string url, string key, object value)
            => RemoteRequest.SetRequestUrl(url).SetQueryParams(key, value);

        /// <summary>
        /// 设置 Authorization
        /// </summary>
        /// <param name="url"></param>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetAuthorization(this string url, AuthorizationType type, object value)
            => RemoteRequest.SetRequestUrl(url).SetAuthorization(type, value);

        /// <summary>
        /// 设置请求头
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetHeaders(this string url, IDictionary<string, object> headers)
            => RemoteRequest.SetRequestUrl(url).SetHeaders(headers);

        /// <summary>
        /// 设置请求头
        /// </summary>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetHeaders(this string url, string key, object value)
            => RemoteRequest.SetRequestUrl(url).SetHeaders(key, value);

        /// <summary>
        /// 设置 Body
        /// </summary>
        /// <param name="url"></param>
        /// <param name="body"></param>
        /// <param name="contentType"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetBody(this string url, object body, string contentType = default, Encoding encoding = default)
            => RemoteRequest.SetRequestUrl(url).SetBody(body, contentType, encoding);

        /// <summary>
        /// 设置 Body  Bytes
        /// </summary>
        /// <param name="url"></param>
        /// <param name="bytesData"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetBodyBytes(this string url, params (string Name, byte[] Bytes, string FileName)[] bytesData)
            => RemoteRequest.SetRequestUrl(url).SetBodyBytes(bytesData);

        /// <summary>
        /// 设置内容类型
        /// </summary>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetContentType(this string url, string contentType)
            => RemoteRequest.SetRequestUrl(url).SetContentType(contentType);

        /// <summary>
        /// 设置内容编码
        /// </summary>
        /// <param name="url"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static IHttpRemoteRequest SetContentEncoding(this string url, Encoding encoding)
            => RemoteRequest.SetRequestUrl(url).SetContentEncoding(encoding);

        /// <summary>
        /// 发送 GET 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> GetAsync(this string url, CancellationToken cancellationToken = default)
        {
            return RemoteRequest.SetRequestUrl(url).GetAsync(cancellationToken);
        }

        /// <summary>
        /// 发送 Get 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> GetAsync<T>(this string url, CancellationToken cancellationToken = default)
        {
            return RemoteRequest.SetRequestUrl(url).GetAsync<T>(cancellationToken);
        }

        /// <summary>
        /// 发送 Get 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> GetStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).GetStringAsync(cancellationToken);

        /// <summary>
        /// 发送 Get 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> GetStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).GetStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 POST 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> PostAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PostAsync(cancellationToken);

        /// <summary>
        /// 发送 POST 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> PostAsync<T>(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PostAsync<T>(cancellationToken);

        /// <summary>
        /// 发送 POST 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> PostStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PostStringAsync(cancellationToken);

        /// <summary>
        /// 发送 POST 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> PostStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PostStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 PUT 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> PutAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PutAsync(cancellationToken);

        /// <summary>
        /// 发送 PUT 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> PutAsync<T>(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PutAsync<T>(cancellationToken);

        /// <summary>
        /// 发送 PUT 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> PutStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PutStringAsync(cancellationToken);

        /// <summary>
        /// 发送 PUT 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> PutStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PutStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 DELETE 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> DeleteAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).DeleteAsync(cancellationToken);

        /// <summary>
        /// 发送 DELETE 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> DeleteAsync<T>(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).DeleteAsync<T>(cancellationToken);

        /// <summary>
        /// 发送 DELETE 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> DeleteStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).DeleteStringAsync(cancellationToken);

        /// <summary>
        /// 发送 DELETE 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> DeleteStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).DeleteStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 PATCH 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> PatchAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PatchAsync(cancellationToken);

        /// <summary>
        /// 发送 PATCH 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> PatchAsync<T>(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PatchAsync<T>(cancellationToken);

        /// <summary>
        /// 发送 Patch 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> PatchAsStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PatchAsStringAsync(cancellationToken);

        /// <summary>
        /// 发送 PATCH 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> PatchAsStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).PatchAsStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 HEAD 请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> HeadAsync<T>(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).HeadAsync<T>(cancellationToken);

        /// <summary>
        /// 发送 HEAD 请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> HeadStreamAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).HeadStreamAsync(cancellationToken);

        /// <summary>
        /// 发送 Head 请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> HeadAsStringAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).HeadAsStringAsync(cancellationToken);

        /// <summary>
        /// 发送 HEAD 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HttpResponseMessage> HeadAsync(this string url, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).HeadAsync(cancellationToken);

        /// <summary>
        /// 发送请求返回 T 对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="httpMethod"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<T> SendAsync<T>(this string url, HttpMethod httpMethod, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).SendAsync<T>(httpMethod, cancellationToken);

        /// <summary>
        /// 发送请求返回 String
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpMethod"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> SendStringAsync(this string url, HttpMethod httpMethod, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).SendStringAsync(httpMethod, cancellationToken);

        /// <summary>
        /// 发送请求返回 Stream
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpMethod"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<Stream> SendStreamAsync(this string url, HttpMethod httpMethod, CancellationToken cancellationToken = default)
            => RemoteRequest.SetRequestUrl(url).SendStreamAsync(httpMethod, cancellationToken);

        private static IHttpRemoteRequest RemoteRequest => App.GetRequiredService<IHttpRemoteRequest>();
    }
}
